package com.fz.us.admin.base.utils;

import org.apache.commons.lang3.StringUtils;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.*;
import java.util.HashSet;
import java.util.Set;

public class DataUtil {

	public static void main(String[] args){
		Date date1 = StringToDate("2015-12-27");
		Date date2 = StringToDate("2016-01-01");
		System.out.println("---"+DateToString(date1)+"---");
		System.out.println(getWeekOfYear(date1));
		System.out.println(DateToString(getMinDateOfWeek(date1)));
		System.out.println(DateToString(getMaxDateOfWeek(date1)));
		System.out.println("---"+DateToString(date2)+"---");
		System.out.println(getWeekOfYear(date2));
		System.out.println(DateToString(getMinDateOfWeek(date2)));
		System.out.println(DateToString(getMaxDateOfWeek(date2)));
		System.out.println("---"+DateToString(new Date())+"---");
		System.out.println(getWeekOfYear(new Date()));
		System.out.println(DateToString(getMinDateOfWeek(new Date())));
		System.out.println(DateToString(getMaxDateOfWeek(new Date())));
	}

	public final static String PATTERN_TIME = "yyyy-MM-dd HH:mm:ss";
	public final static String PATTERN_MIN = "yyyy-MM-dd HH:mm";
	public final static String PATTERN_DAY = "yyyy-MM-dd";

	private final static String YESTODAY = "昨天";

	private final static ThreadLocal<SimpleDateFormat> dateFormater = new ThreadLocal<SimpleDateFormat>() {
		@Override
		protected SimpleDateFormat initialValue() {
			return new SimpleDateFormat(PATTERN_TIME);
		}
	};

	private final static ThreadLocal<SimpleDateFormat> dateFormater2 = new ThreadLocal<SimpleDateFormat>() {
		@Override
		protected SimpleDateFormat initialValue() {
			return new SimpleDateFormat(PATTERN_MIN);
		}
	};

	private final static ThreadLocal<SimpleDateFormat> dateFormater3 = new ThreadLocal<SimpleDateFormat>() {
		@Override
		protected SimpleDateFormat initialValue() {
			return new SimpleDateFormat(PATTERN_DAY);
		}
	};

	/**
	 * 功能: 返回周数
	 *
	 * @param date 日期对象
	 * @return int
	 */
	public static int getWeekOfYear(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setMinimalDaysInFirstWeek(7);
		calendar.setFirstDayOfWeek(Calendar.MONDAY);
		calendar.setTime(date);
		return calendar.get(Calendar.WEEK_OF_YEAR);
	}

	/**
	 * 功能: 返回星期数(周日 = 1)
	 *
	 * @param date 日期对象
	 * @return int
	 */
	public static int getDayOfWeek(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.DAY_OF_WEEK);
	}

	/**
	 * 功能: 将日期对象按照某种格式进行转换，返回转换后的字符串
	 *
	 * @param date 日期对象
	 * @param pattern 转换格式 例：yyyy-MM-dd
	 * @return String
	 */
	public static String DateToString(Date date, String pattern) {
		String strDateTime = null;
		SimpleDateFormat formater = new SimpleDateFormat(pattern);
		strDateTime = date == null ? null : formater.format(date);
		return strDateTime;
	}

	public static String year(Date date) {
		return DateToString(date,"yyyy");
	}
	public static String month(Date date) {
		return DateToString(date,"MM");
	}
	public static String day(Date date) {
		return DateToString(date,"dd");
	}

	/**
	 * 功能: 将传入的日期对象按照yyyy-MM-dd格式转换成字符串返回
	 *
	 * @param date 日期对象
	 * @return String
	 */
	public static String DateToString(Date date) {
		return date == null ? null : DateToString(date, PATTERN_DAY);
	}

	/**
	 * 功能: 将传入的日期对象按照yyyy-MM-dd HH:mm格式转换成字符串返回
	 *
	 * @param date 日期对象
	 * @return String
	 */
	public static String DateMinToString(Date date) {
		return date == null ? null : DateToString(date, PATTERN_MIN);
	}

	/**
	 * 功能: 将传入的日期对象按照yyyy-MM-dd HH:mm:ss格式转换成字符串返回
	 *
	 * @param date 日期对象
	 * @return String
	 */
	public static String DateTimeToString(Date date) {
		return date == null ? null : DateToString(date, PATTERN_TIME);
	}

	/**
	 * 功能: 将插入的字符串按格式转换成对应的日期对象
	 *
	 * @param str 字符串
	 * @param pattern 格式
	 * @return Date
	 */
	public static Date StringToDate(String str, String pattern) {
		Date dateTime = null;
		try {
			if (str != null && !str.equals("")) {
				SimpleDateFormat formater = new SimpleDateFormat(pattern);
				dateTime = formater.parse(str);
			}
		} catch (Exception ex) {
		}
		return dateTime;
	}

	/**
	 * 功能: 将传入的字符串按yyyy-MM-dd格式转换成对应的日期对象
	 *
	 * @param str 需要转换的字符串
	 * @return Date
	 */
	public static Date StringToDate(String str) {
		return StringToDate(str, PATTERN_DAY);
	}

	/**
	 * 功能: 将传入的字符串按yyyy-MM-dd HH:mm格式转换成对应的日期对象
	 *
	 * @param str 需要转换的字符串
	 * @return Date
	 */
	public static Date StringToDateMin(String str) {
		return StringToDate(str, PATTERN_MIN);
	}

	/**
	 * 功能: 将传入的字符串按yyyy-MM-dd HH:mm:ss格式转换成对应的日期对象
	 *
	 * @param str 需要转换的字符串
	 * @return Date
	 */
	public static Date StringToDateTime(String str) {
		return StringToDate(str, PATTERN_TIME);
	}

	/**
	 * 功能: 将传入的字符串转换成对应的Timestamp对象
	 *
	 * @param str 待转换的字符串
	 * @return Timestamp 转换之后的对象
	 * @throws Exception
	 *             Timestamp
	 */
	public static Timestamp StringToDateHMS(String str) throws Exception {
		Timestamp time = null;
		time = Timestamp.valueOf(str);
		return time;
	}

	/**
	 * 功能: 返回年份开始时刻
	 *
	 * @param year 年份
	 * @return String
	 */
	public static Date getMinDateOfYear(int year) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, calendar.getActualMinimum(Calendar.MONTH));
		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 功能: 返回日期对象当天开始时刻
	 *
	 * @param year 年份
	 * @param monthOfYear 月份
	 * @return String
	 */
	public static Date getMinDateOfMonth(int year, int monthOfYear) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, monthOfYear);
		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 功能: 返回日期对象当天开始时刻
	 *
	 * @param year 年份
	 * @param monthOfYear 月份
	 * @param dayOfMonth 天
	 * @return String
	 */
	public static Date getMinHourOfDate(int year, int monthOfYear, int dayOfMonth) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, monthOfYear);
		calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 功能: 返回日期对象当天开始时刻
	 *
	 * @param weekYear 年份
	 * @param weekOfYear 周
	 * @param dayOfWeek 星期
	 * @return String
	 */
	public static Date getDateOfWeek(int weekYear, int weekOfYear, int dayOfWeek) {
		Calendar calendar = Calendar.getInstance();
		calendar.setMinimalDaysInFirstWeek(7);
		calendar.setFirstDayOfWeek(Calendar.MONDAY);
		calendar.set(Calendar.YEAR, weekOfYear);
		calendar.set(Calendar.WEEK_OF_YEAR, weekOfYear);
		calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 功能: 返回日期对象当周开始时刻
	 *
	 * @param date 日期对象
	 * @return String
	 */
	public static Date getMinDateOfWeek(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setMinimalDaysInFirstWeek(7);
		calendar.setFirstDayOfWeek(Calendar.MONDAY);
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 功能: 返回日期对象当周结束时刻
	 *
	 * @param date 日期对象
	 * @return String
	 */
	public static Date getMaxDateOfWeek(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setMinimalDaysInFirstWeek(7);
		calendar.setFirstDayOfWeek(Calendar.MONDAY);
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 功能: 返回日期对象当月开始时刻
	 *
	 * @param date 日期对象
	 * @return String
	 */
	public static Date getMinDateOfMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 功能: 返回日期对象当天开始时刻
	 *
	 * @param date 日期对象
	 * @return String
	 */
	public static Date getMinHourOfDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 功能: 返回日期对象当天结束时刻
	 *
	 * @param date 日期对象
	 * @return String
	 */
	public static Date getMaxHourOfDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 功能: 返回日期对象当前小时开始时刻
	 *
	 * @param date 日期对象
	 * @return String
	 */
	public static Date getMinMinOfHour(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 功能: 返回日期对象当前分钟开始时刻
	 *
	 * @param date 日期对象
	 * @return String
	 */
	public static Date getMinSecOfMin(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND));
		return calendar.getTime();
	}

	/**
	 * 功能：返回传入日期对象（date）之后afterYears年数的日期对象
	 *
	 * @param date 日期对象
	 * @param afterYears 往后年数
	 * @return Date
	 */
	public static Date getAfterYears(Date date, int afterYears) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.YEAR, afterYears);
		return cal.getTime();
	}

	/**
	 * 功能：返回传入日期对象（date）之后afterMonths月数的日期对象
	 *
	 * @param date 日期对象
	 * @param afterMonths 往后月数
	 * @return Date
	 */
	public static Date getAfterMonths(Date date, int afterMonths) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, afterMonths);
		return cal.getTime();
	}

	/**
	 * 功能：返回传入日期对象（date）之后afterDays天数的日期对象
	 *
	 * @param date 日期对象
	 * @param afterDays 往后天数
	 * @return Date
	 */
	public static Date getAfterDay(Date date, int afterDays) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DAY_OF_MONTH, afterDays);
		return cal.getTime();
	}

    /**
     * 功能：返回传入日期对象（date）之后afterHours分钟数的日期对象
     *
     * @param date 日期对象
     * @param afterHours 往后天数小时数
     * @return Date
     */
    public static Date getAfterHours(Date date, int afterHours) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.HOUR_OF_DAY, afterHours);
        return cal.getTime();
    }

	/**
	 * 功能：返回传入日期对象（date）之后afterMinutes分钟数的日期对象
	 *
	 * @param date 日期对象
	 * @param afterMinutes 往后天数正数，否则负数
	 * @return Date
	 */
	public static Date getAfterMinutes(Date date, int afterMinutes) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MINUTE, afterMinutes);
		return cal.getTime();
	}

	/**
	 * 功能：返回传入日期对象（date）之后afterTimes时间的日期对象
	 *
	 * @param date 日期对象
	 * @param afterTimes 往后时间正数，否则负数
	 * @return Date 返回值
	 */
	public static Date getAfterTimes(Date date, long afterTimes) {
		return new Date(date.getTime()+afterTimes);
	}

    /**
     * 功能: 返回date1与date2相差的年数
     *
     * @param date1
     * @param date2
     * @return int
     */
    public static int YearDiff(Date date1, Date date2) {
        int i = (int) ((date1.getTime() - date2.getTime()) / 3600 / 24 / 1000 /365);
        return i;
    }

	/**
	 * 功能: 返回date1与date2相差的天数
	 *
	 * @param date1
	 * @param date2
	 * @return int
	 */
	public static int DateDiff(Date date1, Date date2) {
		int i = (int) ((date1.getTime() - date2.getTime()) / 3600 / 24 / 1000);
		return i;
	}

	/**
	 * 功能: 返回dayOfWeek1与dayOfWeek2相差的天数(工作日)
	 *
	 * @param dayOfWeek1
	 * @param dayOfWeek2
	 * @return int
	 */
	private static int DateDiff_Work_InWeek(int dayOfWeek1, int dayOfWeek2) {
		int diff = 0;
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek2);
		while (calendar.get(Calendar.DAY_OF_WEEK) != dayOfWeek1) {
			if (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY && calendar.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
				diff++;
			}
			calendar.add(Calendar.DAY_OF_WEEK, 1);
		}
		return diff;
	}

	/**
	 * 功能: 返回date1与date2相差的天数 (工作日)
	 *
	 * @param date1
	 * @param date2
	 * @return int
	 */
	public static int DateDiff_Work(Date date1, Date date2) {
		int dateDiff = DateDiff(date1, date2);
		int weekDiff = dateDiff/7;
		if (dateDiff%7 == 0) {
			return weekDiff * 5;
		} else {
			return weekDiff * 5 + DateDiff_Work_InWeek(getDayOfWeek(date1), getDayOfWeek(date2));
		}
	}

	/**
	 * 功能: 返回date1与date2相差的分钟数
	 *
	 * @param date1
	 * @param date2
	 * @return int
	 */
	public static long MinDiff(Date date1, Date date2) {
		long i = (long) ((date1.getTime() - date2.getTime()) / 1000 / 60);
		return i;
	}

	/**
	 * 功能: 返回date1与date2相差的毫秒数
	 *
	 * @param date1
	 * @param date2
	 * @return int
	 */
	public static long TimeDiff(Date date1, Date date2) {
		long i = (long) ((date1.getTime() - date2.getTime()));
		return i;
	}

	/**
	 * 以友好的方式显示时间
	 * @param time
	 * @return
	 */
	public static String friendly_time(Date time) {
		if(time == null) {
			return "Unknown";
		}
		String ftime = "";
		Calendar cal = Calendar.getInstance();

		//判断是否是同一天
		String curDate = dateFormater3.get().format(cal.getTime());
		String paramDate = dateFormater3.get().format(time);
		if(curDate.equals(paramDate)){
			int hour = (int)((cal.getTimeInMillis() - time.getTime())/3600000);
			if(hour == 0)
				ftime = Math.max((cal.getTimeInMillis() - time.getTime()) / 60000,1)+"分钟前";
			else
				ftime = hour+"小时前";
			return ftime;
		}

		long lt = time.getTime()/86400000;
		long ct = cal.getTimeInMillis()/86400000;
		int days = (int)(ct - lt);
		if(days == 0){
			int hour = (int)((cal.getTimeInMillis() - time.getTime())/3600000);
			if(hour == 0)
				ftime = Math.max((cal.getTimeInMillis() - time.getTime()) / 60000,1)+"分钟前";
			else
				ftime = hour+"小时前";
		}
		else if(days == 1){
			ftime = "昨天";
		}
		else if(days == 2){
			ftime = "前天";
		}
		else if(days > 2 && days <= 10){
			ftime = days+"天前";
		}
		else if(days > 10){
			ftime = dateFormater3.get().format(time);
		}
		return ftime;
	}

	/**
	 * 返回日期之间的日期列表
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static Set<String> getBewteenDates(Date date1, Date date2) {
		Set<String> dates = new HashSet<String>();
		if(date1!=null){
			if(date2!=null){
				Date tempDate = StringToDate(DateToString(date1));
				while(tempDate.getTime()<=date2.getTime()){
					dates.add(DateToString(tempDate));
					tempDate = getAfterDay(tempDate, 1);
				}
			}else{
				dates.add(DateToString(date1));
			}
		}
		return dates;
	}

	/**
	 * 返回日期之间的日期列表
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static Set<String> getBewteenDates(Date date1, Date date2, Date begin, Date end) {
		Set<String> dates = new HashSet<String>();
		if(date1!=null){
			if(date2!=null){
				Date tempDate = getMinHourOfDay(date1);
				while(tempDate.getTime()<=date2.getTime()){
					if(tempDate.getTime()>=begin.getTime()&&tempDate.getTime()<end.getTime()){
						dates.add(DateToString(tempDate));
					}
					tempDate = getAfterDay(tempDate, 1);
				}
			}else{
				dates.add(DateToString(date1));
			}
		}
		return dates;
	}

}
